import { defineStore } from 'pinia';
import { fabric } from '@/utils/fabricWrapper';
import { useEditorStore } from './editor';
import { useSettingsStore } from './settings';
import { eventBus } from '@/utils/eventBus';
import type { Element, ElementType } from '@/types';

/**
 * 元素存储
 * 管理编辑器中的所有元素
 */
export const useElementsStore = defineStore('elements', {
  state: () => ({
    elements: [] as Element[],
    nextId: 1,
    clipboard: null as fabric.Object | null
  }),
  
  getters: {
    /**
     * 获取所有元素
     */
    allElements: (state) => state.elements,
    
    /**
     * 按ID获取元素
     */
    getElementById: (state) => (id: string) => state.elements.find(el => el.id === id),
    
    /**
     * 获取可见元素
     */
    visibleElements: (state) => state.elements.filter(el => el.isVisible),
    
    /**
     * 获取按Z-index排序的元素
     */
    sortedElements: (state) => [...state.elements].sort((a, b) => a.zIndex - b.zIndex),
    
    /**
     * 获取特定类型的元素
     */
    getElementsByType: (state) => (type: string) => state.elements.filter(el => el.type === type),
    
    /**
     * 获取锁定的元素
     */
    lockedElements: (state) => state.elements.filter(el => el.isLocked),
    
    /**
     * 获取未锁定的元素
     */
    unlockedElements: (state) => state.elements.filter(el => !el.isLocked),
    
    /**
     * 获取选中的元素
     */
    selectedElements: (state) => {
      const editorStore = useEditorStore();
      return state.elements.filter(el => 
        editorStore.selection.selectedElementIds.includes(el.id)
      );
    }
  },
  
  actions: {
    /**
     * 初始化元素管理器
     * @param canvas Fabric.js 画布实例
     */
    initElementManager(canvas: fabric.Canvas) {
      // 监听画布事件
      this.setupCanvasEvents(canvas);
      
      // 监听事件总线事件
      this.setupEventBusListeners();
    },
    
    /**
     * 设置画布事件监听
     * @param canvas Fabric.js 画布实例
     */
    setupCanvasEvents(canvas: fabric.Canvas) {
      // 监听对象添加事件
      canvas.on('object:added', (e) => {
        if (!e.target) return;
        
        // 如果对象没有ID，则为其分配一个ID
        if (!e.target.id) {
          e.target.id = `element-${this.nextId++}`;
        }
        
        // 将对象添加到元素列表
        this.addElementFromFabricObject(e.target);
      });
      
      // 监听对象移除事件
      canvas.on('object:removed', (e) => {
        if (!e.target || !e.target.id) return;
        
        // 从元素列表中移除对象
        this.removeElement(e.target.id as string);
      });
    },
    
    /**
     * 设置事件总线监听
     */
    setupEventBusListeners() {
      // 监听元素选择事件
      eventBus.on('element:selected', (payload) => {
        if (payload && payload.elementId) {
          this.selectElement(payload.elementId);
        }
      });
      
      // 监听元素取消选择事件
      eventBus.on('element:deselected', () => {
        this.deselectAllElements();
      });
      
      // 监听元素修改事件
      eventBus.on('element:modified', (payload) => {
        if (payload && payload.elementId && payload.element) {
          this.updateElementFromFabricObject(payload.elementId, payload.element);
        }
      });
    },
    
    /**
     * 从Fabric对象创建元素
     * @param fabricObject Fabric.js 对象
     */
    addElementFromFabricObject(fabricObject: fabric.Object) {
      // 确保对象有ID
      const id = fabricObject.id as string || `element-${this.nextId++}`;
      fabricObject.id = id;
      
      // 确定元素类型
      let type: ElementType = 'shape';
      if (fabricObject instanceof fabric.IText) {
        type = 'text';
      } else if (fabricObject instanceof fabric.Image) {
        type = 'image';
      } else if (fabricObject instanceof fabric.Group) {
        type = 'group';
      }
      
      // 创建元素对象
      const element: Element = {
        id,
        type,
        fabricObject,
        isSelected: false,
        isLocked: fabricObject.lockMovementX && fabricObject.lockMovementY,
        isVisible: fabricObject.visible !== false,
        position: { 
          x: fabricObject.left || 0, 
          y: fabricObject.top || 0 
        },
        size: { 
          width: fabricObject.width || 0, 
          height: fabricObject.height || 0 
        },
        rotation: fabricObject.angle || 0,
        opacity: fabricObject.opacity || 1,
        zIndex: this.elements.length > 0 
          ? Math.max(...this.elements.map(el => el.zIndex)) + 1 
          : 1
      };
      
      // 添加到元素列表
      this.elements.push(element);
      
      // 发送元素添加事件
      eventBus.emit('element:added', { element });
      
      return id;
    },
    
    /**
     * 从Fabric对象更新元素
     * @param id 元素ID
     * @param fabricObject Fabric.js 对象
     */
    updateElementFromFabricObject(id: string, fabricObject: fabric.Object) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素属性
      element.fabricObject = fabricObject;
      element.position = { 
        x: fabricObject.left || 0, 
        y: fabricObject.top || 0 
      };
      element.size = { 
        width: fabricObject.width || 0, 
        height: fabricObject.height || 0 
      };
      element.rotation = fabricObject.angle || 0;
      element.opacity = fabricObject.opacity || 1;
      element.isLocked = fabricObject.lockMovementX && fabricObject.lockMovementY;
      element.isVisible = fabricObject.visible !== false;
      
      // 发送元素更新事件
      eventBus.emit('element:updated', { element });
    },
    
    /**
     * 添加元素
     * @param element 元素对象（不包含ID和zIndex）
     */
    addElement(element: Omit<Element, 'id' | 'zIndex'>) {
      const id = `element-${this.nextId++}`;
      const zIndex = this.elements.length > 0 
        ? Math.max(...this.elements.map(el => el.zIndex)) + 1 
        : 1;
      
      const newElement = {
        ...element,
        id,
        zIndex
      } as Element;
      
      this.elements.push(newElement);
      
      // 发送元素添加事件
      eventBus.emit('element:added', { element: newElement });
      
      return id;
    },
    
    /**
     * 更新元素
     * @param id 元素ID
     * @param properties 要更新的属性
     */
    updateElement(id: string, properties: Partial<Element>) {
      const index = this.elements.findIndex(el => el.id === id);
      if (index === -1) return;
      
      // 更新元素属性
      this.elements[index] = {
        ...this.elements[index],
        ...properties
      };
      
      // 如果有Fabric对象，也更新它
      const fabricObject = this.elements[index].fabricObject;
      if (fabricObject) {
        // 更新位置
        if (properties.position) {
          fabricObject.set({
            left: properties.position.x,
            top: properties.position.y
          });
        }
        
        // 更新大小
        if (properties.size) {
          fabricObject.set({
            width: properties.size.width,
            height: properties.size.height,
            scaleX: 1,
            scaleY: 1
          });
        }
        
        // 更新旋转
        if (properties.rotation !== undefined) {
          fabricObject.set({ angle: properties.rotation });
        }
        
        // 更新透明度
        if (properties.opacity !== undefined) {
          fabricObject.set({ opacity: properties.opacity });
        }
        
        // 更新锁定状态
        if (properties.isLocked !== undefined) {
          fabricObject.set({
            lockMovementX: properties.isLocked,
            lockMovementY: properties.isLocked,
            lockRotation: properties.isLocked,
            lockScalingX: properties.isLocked,
            lockScalingY: properties.isLocked
          });
        }
        
        // 更新可见性
        if (properties.isVisible !== undefined) {
          fabricObject.set({ visible: properties.isVisible });
        }
        
        // 请求重绘
        const editorStore = useEditorStore();
        const canvas = editorStore.canvas.fabricCanvas;
        canvas?.requestRenderAll();
      }
      
      // 发送元素更新事件
      eventBus.emit('element:updated', { element: this.elements[index] });
    },
    
    /**
     * 删除元素
     * @param id 元素ID
     */
    removeElement(id: string) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 从画布中移除Fabric对象
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (canvas && element.fabricObject) {
        canvas.remove(element.fabricObject);
      }
      
      // 从元素列表中移除
      this.elements = this.elements.filter(el => el.id !== id);
      
      // 发送元素删除事件
      eventBus.emit('element:removed', { elementId: id });
    },
    
    /**
     * 选择元素
     * @param id 元素ID
     */
    selectElement(id: string) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新选择状态
      element.isSelected = true;
      
      // 选择Fabric对象
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (canvas && element.fabricObject) {
        canvas.setActiveObject(element.fabricObject);
        canvas.requestRenderAll();
      }
    },
    
    /**
     * 取消选择所有元素
     */
    deselectAllElements() {
      // 更新所有元素的选择状态
      this.elements.forEach(element => {
        element.isSelected = false;
      });
      
      // 取消画布选择
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (canvas) {
        canvas.discardActiveObject();
        canvas.requestRenderAll();
      }
    },
    
    /**
     * 锁定元素
     * @param id 元素ID
     */
    lockElement(id: string) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素锁定状态
      this.updateElement(id, { isLocked: true });
      
      // 锁定Fabric对象
      if (element.fabricObject) {
        element.fabricObject.set({
          lockMovementX: true,
          lockMovementY: true,
          lockRotation: true,
          lockScalingX: true,
          lockScalingY: true
        });
      }
      
      // 发送元素锁定事件
      eventBus.emit('element:locked', { elementId: id });
    },
    
    /**
     * 解锁元素
     * @param id 元素ID
     */
    unlockElement(id: string) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素锁定状态
      this.updateElement(id, { isLocked: false });
      
      // 解锁Fabric对象
      if (element.fabricObject) {
        element.fabricObject.set({
          lockMovementX: false,
          lockMovementY: false,
          lockRotation: false,
          lockScalingX: false,
          lockScalingY: false
        });
      }
      
      // 发送元素解锁事件
      eventBus.emit('element:unlocked', { elementId: id });
    },
    
    /**
     * 显示元素
     * @param id 元素ID
     */
    showElement(id: string) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素可见性
      this.updateElement(id, { isVisible: true });
      
      // 显示Fabric对象
      if (element.fabricObject) {
        element.fabricObject.set({ visible: true });
      }
      
      // 请求重绘
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      canvas?.requestRenderAll();
      
      // 发送元素显示事件
      eventBus.emit('element:shown', { elementId: id });
    },
    
    /**
     * 隐藏元素
     * @param id 元素ID
     */
    hideElement(id: string) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素可见性
      this.updateElement(id, { isVisible: false });
      
      // 隐藏Fabric对象
      if (element.fabricObject) {
        element.fabricObject.set({ visible: false });
      }
      
      // 请求重绘
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      canvas?.requestRenderAll();
      
      // 发送元素隐藏事件
      eventBus.emit('element:hidden', { elementId: id });
    },
    
    /**
     * 移动元素
     * @param id 元素ID
     * @param x X坐标
     * @param y Y坐标
     */
    moveElement(id: string, x: number, y: number) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素位置
      this.updateElement(id, { position: { x, y } });
      
      // 移动Fabric对象
      if (element.fabricObject) {
        element.fabricObject.set({
          left: x,
          top: y
        });
        
        // 请求重绘
        const editorStore = useEditorStore();
        const canvas = editorStore.canvas.fabricCanvas;
        canvas?.requestRenderAll();
      }
      
      // 发送元素移动事件
      eventBus.emit('element:moved', { 
        elementId: id, 
        position: { x, y } 
      });
    },
    
    /**
     * 调整元素大小
     * @param id 元素ID
     * @param width 宽度
     * @param height 高度
     */
    resizeElement(id: string, width: number, height: number) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素大小
      this.updateElement(id, { size: { width, height } });
      
      // 调整Fabric对象大小
      if (element.fabricObject) {
        element.fabricObject.set({
          width,
          height,
          scaleX: 1,
          scaleY: 1
        });
        
        // 请求重绘
        const editorStore = useEditorStore();
        const canvas = editorStore.canvas.fabricCanvas;
        canvas?.requestRenderAll();
      }
      
      // 发送元素调整大小事件
      eventBus.emit('element:resized', { 
        elementId: id, 
        size: { width, height } 
      });
    },
    
    /**
     * 旋转元素
     * @param id 元素ID
     * @param rotation 旋转角度
     */
    rotateElement(id: string, rotation: number) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素旋转
      this.updateElement(id, { rotation });
      
      // 旋转Fabric对象
      if (element.fabricObject) {
        element.fabricObject.set({ angle: rotation });
        
        // 请求重绘
        const editorStore = useEditorStore();
        const canvas = editorStore.canvas.fabricCanvas;
        canvas?.requestRenderAll();
      }
      
      // 发送元素旋转事件
      eventBus.emit('element:rotated', { 
        elementId: id, 
        rotation 
      });
    },
    
    /**
     * 设置元素透明度
     * @param id 元素ID
     * @param opacity 透明度
     */
    setElementOpacity(id: string, opacity: number) {
      // 确保透明度在有效范围内
      opacity = Math.max(0, Math.min(1, opacity));
      
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素透明度
      this.updateElement(id, { opacity });
      
      // 更新Fabric对象透明度
      if (element.fabricObject) {
        element.fabricObject.set({ opacity });
        
        // 请求重绘
        const editorStore = useEditorStore();
        const canvas = editorStore.canvas.fabricCanvas;
        canvas?.requestRenderAll();
      }
      
      // 发送元素透明度变更事件
      eventBus.emit('element:opacity-changed', { 
        elementId: id, 
        opacity 
      });
    },
    
    /**
     * 设置元素Z-index
     * @param id 元素ID
     * @param zIndex Z-index
     */
    setElementZIndex(id: string, zIndex: number) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 更新元素Z-index
      this.updateElement(id, { zIndex });
      
      // 调整Fabric对象层级
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (canvas && element.fabricObject) {
        // 根据Z-index重新排序所有对象
        const sortedElements = this.sortedElements;
        sortedElements.forEach((el, index) => {
          if (el.fabricObject) {
            canvas.moveTo(el.fabricObject, index);
          }
        });
        
        canvas.requestRenderAll();
      }
      
      // 发送元素Z-index变更事件
      eventBus.emit('element:zindex-changed', { 
        elementId: id, 
        zIndex 
      });
    },
    
    /**
     * 将元素移到最前
     * @param id 元素ID
     */
    bringToFront(id: string) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 计算新的Z-index
      const maxZIndex = Math.max(...this.elements.map(el => el.zIndex));
      const newZIndex = maxZIndex + 1;
      
      // 更新元素Z-index
      this.setElementZIndex(id, newZIndex);
      
      // 发送元素置顶事件
      eventBus.emit('element:brought-to-front', { elementId: id });
    },
    
    /**
     * 将元素移到最后
     * @param id 元素ID
     */
    sendToBack(id: string) {
      const element = this.getElementById(id);
      if (!element) return;
      
      // 计算新的Z-index
      const minZIndex = Math.min(...this.elements.map(el => el.zIndex));
      const newZIndex = minZIndex - 1;
      
      // 更新元素Z-index
      this.setElementZIndex(id, newZIndex);
      
      // 发送元素置底事件
      eventBus.emit('element:sent-to-back', { elementId: id });
    },
    
    /**
     * 创建文本元素
     * @param text 文本内容
     * @param x X坐标
     * @param y Y坐标
     */
    createTextElement(text: string, x: number, y: number) {
      const editorStore = useEditorStore();
      const settingsStore = useSettingsStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (!canvas) return;
      
      // 创建文本对象
      const textObject = new fabric.IText(text, {
        left: x,
        top: y,
        fontFamily: settingsStore.defaultFont,
        fontSize: settingsStore.defaultFontSize,
        fill: settingsStore.defaultColor,
        originX: 'center',
        originY: 'center'
      });
      
      // 添加到画布
      canvas.add(textObject);
      canvas.setActiveObject(textObject);
      canvas.requestRenderAll();
      
      // 返回元素ID
      return textObject.id;
    },
    
    /**
     * 创建形状元素
     * @param type 形状类型
     * @param x X坐标
     * @param y Y坐标
     * @param width 宽度
     * @param height 高度
     */
    createShapeElement(type: ShapeType, x: number, y: number, width: number, height: number) {
      const editorStore = useEditorStore();
      const settingsStore = useSettingsStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (!canvas) return;
      
      let shapeObject: fabric.Object;
      
      // 根据形状类型创建对象
      switch (type) {
        case 'rect':
          shapeObject = new fabric.Rect({
            left: x,
            top: y,
            width,
            height,
            fill: settingsStore.defaultFillColor,
            stroke: settingsStore.defaultStrokeColor,
            strokeWidth: settingsStore.defaultStrokeWidth,
            originX: 'center',
            originY: 'center'
          });
          break;
        case 'circle':
          shapeObject = new fabric.Circle({
            left: x,
            top: y,
            radius: Math.min(width, height) / 2,
            fill: settingsStore.defaultFillColor,
            stroke: settingsStore.defaultStrokeColor,
            strokeWidth: settingsStore.defaultStrokeWidth,
            originX: 'center',
            originY: 'center'
          });
          break;
        case 'ellipse':
          shapeObject = new fabric.Ellipse({
            left: x,
            top: y,
            rx: width / 2,
            ry: height / 2,
            fill: settingsStore.defaultFillColor,
            stroke: settingsStore.defaultStrokeColor,
            strokeWidth: settingsStore.defaultStrokeWidth,
            originX: 'center',
            originY: 'center'
          });
          break;
        case 'line':
          shapeObject = new fabric.Line([x, y, x + width, y + height], {
            stroke: settingsStore.defaultStrokeColor,
            strokeWidth: settingsStore.defaultStrokeWidth,
            originX: 'center',
            originY: 'center'
          });
          break;
        case 'polygon':
          // 创建多边形（示例为五边形）
          const points = [
            { x: x, y: y - height / 2 },
            { x: x + width / 2, y: y },
            { x: x + width / 4, y: y + height / 2 },
            { x: x - width / 4, y: y + height / 2 },
            { x: x - width / 2, y: y }
          ];
          shapeObject = new fabric.Polygon(points, {
            fill: settingsStore.defaultFillColor,
            stroke: settingsStore.defaultStrokeColor,
            strokeWidth: settingsStore.defaultStrokeWidth,
            originX: 'center',
            originY: 'center'
          });
          break;
        case 'path':
          // 创建简单路径（示例为三角形）
          const path = `M ${x} ${y} L ${x + width} ${y} L ${x + width / 2} ${y + height} z`;
          shapeObject = new fabric.Path(path, {
            fill: settingsStore.defaultFillColor,
            stroke: settingsStore.defaultStrokeColor,
            strokeWidth: settingsStore.defaultStrokeWidth,
            originX: 'center',
            originY: 'center'
          });
          break;
        default:
          return;
      }
      
      // 添加到画布
      canvas.add(shapeObject);
      canvas.setActiveObject(shapeObject);
      canvas.requestRenderAll();
      
      // 返回元素ID
      return shapeObject.id;
    },
    
    /**
     * 创建图片元素
     * @param url 图片URL
     * @param x X坐标
     * @param y Y坐标
     */
    createImageElement(url: string, x: number, y: number) {
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (!canvas) return;
      
      // 加载图片
      fabric.Image.fromURL(url, (img) => {
        // 设置图片位置
        img.set({
          left: x,
          top: y,
          originX: 'center',
          originY: 'center'
        });
        
        // 添加到画布
        canvas.add(img);
        canvas.setActiveObject(img);
        canvas.requestRenderAll();
        
        // 发送图片加载完成事件
        eventBus.emit('image:loaded', { 
          element: img,
          elementId: img.id || 'unknown'
        });
      });
    },
    
    /**
     * 创建组合元素
     * @param elementIds 要组合的元素ID数组
     */
    createGroup(elementIds: string[]) {
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (!canvas) return;
      
      // 获取要组合的对象
      const objects: fabric.Object[] = [];
      elementIds.forEach(id => {
        const element = this.getElementById(id);
        if (element && element.fabricObject) {
          objects.push(element.fabricObject);
        }
      });
      
      if (objects.length < 2) return;
      
      // 创建组合
      const group = new fabric.Group(objects, {
        originX: 'center',
        originY: 'center'
      });
      
      // 从画布中移除原始对象
      objects.forEach(obj => {
        canvas.remove(obj);
      });
      
      // 添加组合到画布
      canvas.add(group);
      canvas.setActiveObject(group);
      canvas.requestRenderAll();
      
      // 返回组合ID
      return group.id;
    },
    
    /**
     * 解组
     * @param groupId 组合ID
     */
    ungroup(groupId: string) {
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (!canvas) return;
      
      // 获取组合对象
      const element = this.getElementById(groupId);
      if (!element || !element.fabricObject || !(element.fabricObject instanceof fabric.Group)) {
        return;
      }
      
      const group = element.fabricObject;
      
      // 获取组合中的对象
      const items = group.getObjects();
      
      // 解组
      group.destroy();
      canvas.remove(group);
      
      // 添加解组后的对象到画布
      const newIds: string[] = [];
      items.forEach(item => {
        item.set({
          left: (item.left || 0) + (group.left || 0),
          top: (item.top || 0) + (group.top || 0)
        });
        canvas.add(item);
        newIds.push(item.id as string);
      });
      
      // 选择解组后的对象
      const activeSelection = new fabric.ActiveSelection(items, { canvas });
      canvas.setActiveObject(activeSelection);
      canvas.requestRenderAll();
      
      // 返回解组后的对象ID数组
      return newIds;
    },
    
    /**
     * 清空所有元素
     */
    clearAllElements() {
      const editorStore = useEditorStore();
      const canvas = editorStore.canvas.fabricCanvas;
      if (canvas) {
        canvas.clear();
      }
      
      this.elements = [];
      this.nextId = 1;
      
      // 发送清空事件
      eventBus.emit('elements:cleared');
    }
  }
});